
# 服务

所谓服务，就是向外部提供服务的一些列功能的模块。比如持久化服务——几乎所有中间件中间件都是通过 *持久化服务* 都是和数据库打交道，为了保持良好的架构，应该避免在中间件中直接操作数据库。

服务对数据库的操作尽量通过`tiny-service`隔离开。有些情况，需要裸写`SQL`语句的，也要尽量注意通用性，以备将来随时替换数据库访问层。由于规模并不大，而且用了`Sequelize.js`，目前把持久化层从服务层分离出去的意义并不大，所以目前的分层仍然是根据需要灵活选择：
```
+--------------------------------------------+
|                                            |
|             请求-响应处理中间件             |
|                                            |
+--------------------------------------------+
|                                            |
|                                            |
|                                            |
|   服务层     +-----------------------------+
|             |                              |
|             |        持久化服务             | 
|             |                              |
+-------------+------------------------------+
```

## 服务的组织

服务按照主题可以分成很多种：
0. 系统安装类相关服务 : 用于提供系统安装时的一系列相关服务，如检查、建表、填数、锁定等
1. 账户类相关服务 : 
    * 密码服务 : 如密码生成、密码比较
    * 用户注册服务 : 如邀请码生成服务、账户可用性检测、过期时间判断、用户创建等
    * 系统资源服务  
    * 角色服务   
    * 用户服务等 :用户查找、用户角色加载等
2. 通用类相关服务 : 分类服务、关键词服务、用户意见服务
3. 邮件类相关服务 
4. 工具类相关服务
5. CMS类相关服务  : 文章、电子书、视频等服务
6. 评论类相关服务  : 评论的创建、回复、点赞等

服务之间可以互相引用，比如评论类服务就必然会引用账户类服务，点赞还会涉及到通用类服务种的用户意见服务。服务内部之间可以直接引用，但是对于外部来说，所有的服务都通过`service/index.js`文件夹暴露，不得直接`require`某个服务子模块。

## `tiny-service`

`Sequelize.js`提供了非常方便的操作数据库的接口，不过大部分持久化服务都是简单的增删改查而已，不让在中间件里操作数据库，意味着就要把数据库操作移到服务层(及服务层以下)。为了遵循`DRY`原则，同时也为了提供更好的适应性，可以引入一层`tiny-service`，通过模型层自动生成部分服务对象——类似于`Spring Data`那样。得益于`JavaScript`与生俱来的灵活性，如果有需要调整的，直接覆盖所生成的对象的相关函数即可。
